<?
class DATEFORMAT
{
	const DMY = 0;
	const MDY = 1;
	const YMD = 2;
}

class DATEUNIT
{
	const MICROSECOND = 'MICROSECOND';
	const SECOND = 'SECOND';
	const MINUTE = 'MINUTE';
	const HOUR = 'HOUR';
	const DAY = 'DAY';
	const WEEK = 'WEEK';
	const MONTH = 'MONTH';
	const QUARTER = 'QUARTER';
	const YEAR = 'YEAR';
}

class DateUtil
{
	/**
	* Return the current Data
	*@param DATEFORMAT $dateFormat
	*@return string 
	*/
	public static function Today($dateFormat = DATEFORMAT::YMD)
	{
		$dateStr = getdate();
		return DateUtil::FormatDate($dateStr[0], $dateFormat);
	}
	
	/**
	 * Get the Date string from a date in timestamp format
	 *
	 * @param int $timestamp
	 * @param DATEFORMAT $dateFormat
	 * @param string $separator
	 * @param bool $showHours
	 * @return string
	 */
	public static function FormatDate($timestamp, $dateFormat = DATEFORMAT::YMD, $separator = "-", $showHours = false)
	{
		$strClock = '';
		if($showHours)
		{
			$strClock = ' %H:%M:%S';
		}
		
		if (strpos(".-/", $separator)===false)
		{
			throw new Exception("Date separator must be . - or /");
		}
		switch ($dateFormat)
		{
			case DATEFORMAT::DMY:
			{
				return strftime("%d$separator%m$separator%Y" . $strClock, $timestamp);
				break;
			}
			case DATEFORMAT::MDY:
			{
				return strftime("%m$separator%d$separator%Y" . $strClock, $timestamp);
				break;
			}
			default:
			{
				return strftime("%Y$separator%m$separator%d" . $strClock, $timestamp);
				break;
			}
		}
	}
	
	/**
	* Add days in a specfied date
	*@param string $date
	*@param int $days
	*@param DATEFORMAT $dateFormat
	*@return string 
	*/
	public static function DateAdd($date, $days, $dateFormat = DATEFORMAT::YMD)
	{
		$timestamp = strtotime("$days day", DateUtil::TimeStampFromStr($date, $dateFormat));
		return DateUtil::FormatDate($timestamp, $dateFormat);
	}
	
	/**
	 * Invervalo de datas
	 *
	 * @param string $date
	 * @param int $value
	 * @param DATEUNIT $unit
	 * @return int
	 */
	public static function Interval($date, $value, $unit)
	{
		return strtotime("$value $unit", DateUtil::ConvertToTimeStamp($date));
	}
	
	/**
	 * Invervalo de datas
	 *
	 * @param string $date
	 * @param int $value
	 * @param DATEUNIT $unit
	 * @return int
	 */
	public static function IntervalToDateTime($date, $value, $unit)
	{
		return DateUtil::FormatDate(DateUtil::Interval($date, $value, $unit), DATEFORMAT::YMD, '-', true);
	}
	
	/**
	 * Invervalo de datas
	 *
	 * @param string $date
	 * @param int $value
	 * @param DATEUNIT $unit
	 * @return int
	 */
	public static function IntervalToBrazilDate($date, $value, $unit)
	{
		return DateUtil::FormatDate(DateUtil::Interval($date, $value, $unit), DATEFORMAT::DMY, '/', true);
	}
	
	
	
	/**
	 * Converte qualquer data para TimeStamp
	 *
	 * @param string $date
	 * @return int
	 */
	public static function ConvertToTimeStamp($date)
	{
		$sep = '-';
		$arrDate = explode(' ', $date);
		if (strpos($arrDate[0], $sep) === false)
		{
			$sep = '/';
		}
		
		$arrDateParts = explode($sep, $arrDate[0]);
		
		//ano primeiro?
		if (strlen($arrDateParts[0]) > 2)
		{
			return DateUtil::TimeStampFromStr($date, DATEFORMAT::YMD);
		}
		
		return DateUtil::TimeStampFromStr($$date, DATEFORMAT::DMY);
	}
	/**
	 * Calcular a diferença entre datas
	 *
	 * Ex.: DateDiff(2007-11-21, 2007-10-21);
	 * Returns 30 days
	 * 
	 * @param string $final_date
	 * @param string $date_initial
	 * @return int
	 */
	public static function DateDiff($final_date, $date_initial)
	{

		list($from_year, $from_month, $from_day) = explode("-", $final_date);
		list($to_year, $to_month, $to_day) = explode("-", $date_initial);

		$from_date = mktime(0, 0, 0, $from_month, $from_day, $from_year);
		$to_date = mktime(0, 0, 0, $to_month, $to_day, $to_year);
		
		$days = ($from_date - $to_date)/86400;

		return ceil($days);
	}  

	/**
	 * Converte de DateTime para uma data em string
	 * Ex.: 2007-10-20 15:25:00 para 20/10/2007 15:25:00
	 *
	 * @param string $date
	 * @param DATEFORMAT $dateformat
	 * @param char $separator
	 * @param bool $showHours
	 * @return string
	 */
	public static function DateFormatFromDateTime($date, $dateformat = DATEFORMAT::YMD, $separator = '-', $showHours = true)
	{
		return self::FormatDate(self::TimeStampFromStr($date, DATEFORMAT::YMD), $dateformat, $separator, $showHours);
	}
	/**
	 * Converte uma data em string para DateTime
	 * ex: 20/10/2007 para 2007-10-20 00:00:00
	 *
	 * @param string $date
	 * @param DATEFORMAT $dateformat
	 * @param char $separator
	 * @param bool $showHours
	 * @return string
	 */
	public static function DateTimeFromStr($date, $dateformat = DATEFORMAT::DMY)
	{
		return self::FormatDate(self::TimeStampFromStr($date, $dateformat), DATEFORMAT::YMD, '-', true);
	}
	/**
	 * Converte uma data em string para Date
	 * ex: 20/10/2007 para 2007-10-20
	 *
	 * @param string $date
	 * @param DATEFORMAT $dateformat
	 * @return string
	 */
	public static function DateFromStr($date, $dateformat = DATEFORMAT::DMY)
	{
		return self::FormatDate(self::TimeStampFromStr($date, $dateformat), DATEFORMAT::YMD, '-', false);
	}
	/**
	 * Converte timestamp para Data
	 * ex: 13123123 para 2007-10-20
	 *
	 * @param int $timestamp
	 * @param DATEFORMAT $dateformat
	 * @return string
	 */
	public static function DateFromTimestamp($timestamp, $dateformat = DATEFORMAT::DMY)
	{
		return self::FormatDate($timestamp, DATEFORMAT::YMD, '-', false);
	}
	/**
	* Get the timestamp from a date string
	*@param strint $date
	*@param DATEFORMAT $dateFormat
	*@return string 
	*/
	public static function TimeStampFromStr($date, $dateFormat = DATEFORMAT::YMD)
	{
		$timestamp = -1;
		switch ($dateFormat)
		{
			case DATEFORMAT::DMY:
			{
				$reg = preg_split("/[^0-9]/", $date);
       			@$timestamp = mktime(0, 0, 0, $reg[1], $reg[0], $reg[2]); 
				break;
			}
			case DATEFORMAT::MDY:
			{
				$reg = preg_split("/[^0-9]/", $date);
       			@$timestamp = mktime(0, 0, 0, $reg[0], $reg[1], $reg[2]); 
				break;
			}
			default:
			{
				$timestamp = strtotime($date);
				break;
			}
		}
		if ($timestamp == -1) 
		{
			throw new DateUtilException(700, "Error in timestamp date formtat");
		}
		else 
		{
			return $timestamp;
		}
	}
	
	/**
	 * Get datetime format from now
	 *
	 * @param DATEFORMAT $dateFormat
	 * @param string $separator
	 * @param bool $showHours
	 * @return string
	 */
	public static function Now($dateFormat = DATEFORMAT::YMD, $separator = '-', $showHours = true)
	{
		$time = '';
		if ($showHours) 
		{
			$time = ' H:i:s';
		}
		
		switch ($dateFormat)
		{
			case DATEFORMAT::DMY:
			{
				return date('d' . $separator . 'm' . $separator . 'Y' . $time);
				break;
			}
			case DATEFORMAT::MDY:
			{
				return date('m' . $separator . 'd' . $separator . 'Y' . $time);
				break;
			}
			default:
			{
				return date('Y' . $separator . 'm' . $separator . 'd'  . $time);
				break;
			}
		}
	}
	
	
	
	/**
	 * Date in full from timestamp and language
	 * Ex: en-us = April 29, 2006
	 * Ex: pt-br = 29 de Abril de 2006
	 *
	 * @param int $timestamp
	 * @param string $lang
	 * @return string
	 */
	public static function DataFull($timestamp, $lang = 'en-us')
	{
		switch ($lang)
		{
			case 'pt-br':
			{
				$arrayDate = getdate($timestamp);
				$month = '';
				switch ($arrayDate['mon']) 
				{
					case 1: $month = 'Janeiro'; break;
					case 2: $month = 'Fevereiro'; break;
					case 3: $month = 'Março'; break;
					case 4: $month = 'Abril'; break;
					case 5: $month = 'Maio'; break;
					case 6: $month = 'Junho'; break;
					case 7: $month = 'Julho'; break;
					case 8: $month = 'Agosto'; break;
					case 9: $month = 'Setembro'; break;
					case 10: $month = 'Outubro'; break;
					case 11: $month = 'Novembro'; break;
					case 12: $month = 'Dezembro'; break;
				}
				return $arrayDate['mday'] . ' de ' . $month . ' de ' . $arrayDate['year'];
				break;
			}
			default:
			{
				return date('F j, Y', $timestamp);
				break;
			}
		}
	}
	
	/**
	 * Get empty datetime format
	 *
	 * @param DATEFORMAT $dateFormat
	 * @param string $separator
	 * @return string
	 */
	public static function EmptyDate($separator = '-')
	{
		return '0000' . $separator . '00' . $separator . '00 00:00:00';
	}
	
	/**
	 * Get timestamp datetime from now
	 *
	 * @return int
	 */
	public static function Timestamp()
	{
		return time();
	}
	
	/**
	 * Get next month
	 * 2007-06
	 *
	 * @return string
	 */
	public static function NextMonth()
	{
		$y = date('Y');
		$m = date('m');
		if ($m == 12)
		{
			$m = 0;
			$y++;
		}
		$m++;
		return "$y-$m";
	}
		
	/**
	 * Get next month more one
	 * 2007-06
	 *
	 * @return string
	 */
	public static function NextMonthMoreOne()
	{
		$y = date('Y');
		$m = date('m');
		if ($m == 12)
		{
			$m = 0;
			$y++;
		}
		$m++;
		if ($m == 12)
		{
			$m = 0;
			$y++;
		}
		$m++;
		return "$y-$m";
	}
	
	/**
	 * Obtem o nome do mês em PT-BR
	 *
	 * @param int $num
	 * @return string
	 */
	public static function BrazilMonth($num)
	{
		switch ($num)
		{
			case 1: $mes = "Janeiro"; break;
			case 2: $mes = "Fevereiro"; break;
			case 3: $mes = "Março"; break;
			case 4: $mes = "Abril"; break;
			case 5: $mes = "Maio"; break;
			case 6: $mes = "Junho"; break;
			case 7: $mes = "Julho"; break;
			case 8: $mes = "Agosto"; break;
			case 9: $mes = "Setembro"; break;
			case 10: $mes = "Outubro"; break;
			case 11: $mes = "Novembro"; break;
			case 12: $mes = "Dezembro"; break;
		}
		return $mes;
	}
	/**
	 * Returns the current Date.
	 *
	 * @param DATEFORMAT $dateFormat
	 * @param string $separator
	 * @return string
	 */
	public static function NowDate($dateFormat = DATEFORMAT::YMD, $separator = '-')
	{
		switch ($dateFormat)
		{
			case DATEFORMAT::DMY:
			{
				return date('d' . $separator . 'm' . $separator . 'Y');
				break;
			}
			case DATEFORMAT::MDY:
			{
				return date('m' . $separator . 'd' . $separator . 'Y');
				break;
			}
			default:
			{
				return date('Y' . $separator . 'm' . $separator . 'd');
				break;
			}
		}
	}
	/**
	 * Returns the current Time
	 *
	 * @return string
	 */
	public static function NowTime()
	{
		$localtime = localtime();
		return date($localtime[2].':'.$localtime[1].':'.$localtime[0]);
	}
	
	/**
	 * Retorna o mês atual
	 * 
	 * 1 -> Janeiro
	 * 2 -> Fevereiro
	 *
	 * @return int
	 */
	public static function Month()
	{
		return intval(date('n'));
	}
}
?>